﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Grain.Crm.DataMigrator.CrmServices;

namespace Grain.Crm.DataMigrator.Infrastructure
{
    public interface IBuildable
    {
        void Build(Builder builder);
    }

    public class Builder
    {
        public string HeaderRow { get; set; }
        public string ContentRow { get; set; }
        public ICrmService Service { get; set; }
        public Container SharedContainer { get; set; }

        public Builder(string headerRow, string contentRow, ICrmService service, Container sharedContainer)
        {
            if(sharedContainer==null)
                throw new ArgumentNullException("sharedContainer");

            if (service == null)
                throw new ArgumentNullException("service");

            HeaderRow = headerRow;
            ContentRow = contentRow;
            Service = service;
            SharedContainer = sharedContainer;
        }

        public void Build(object obj)
        {
            if(obj is ImportEntityTask)
            {
                var task = obj as ImportEntityTask;
                task.SharedContainer = this.SharedContainer;
                task.Service = this.Service;
                task.HeaderRow = this.HeaderRow;
                task.ContentRow = this.ContentRow;

                //build first the container to be able to use the stored values:
                task.Container.Build(this);

                foreach (var searchAttribute in task.SearchAttributes)
                    searchAttribute.Build(this);

                foreach (var appender in task.ValueAppenders)
                    appender.Build(this);

                task.PrimaryKeyAppender.Build(this);

            }
            if (obj is SheetValueResolver)
            {
                (obj as SheetValueResolver).HeaderRow = HeaderRow;
                (obj as SheetValueResolver).ContentRow = ContentRow;
            }
            if (obj is CrmIdResolver)
            {
                (obj as CrmIdResolver).Service = Service;

                foreach (var searchValue in (obj as CrmIdResolver).SearchValues)
                    searchValue.Build(this);
            }
            if (obj is CrmValueResolver)
            {
                (obj as CrmValueResolver).Service = Service;

                foreach (var searchValue in (obj as CrmValueResolver).SearchValues)
                    searchValue.Build(this);
            }
            if (obj is ValueAppender)
            {
                (obj as ValueAppender).Service = Service;
                (obj as ValueAppender).HeaderRow = HeaderRow;
                (obj as ValueAppender).ContentRow = ContentRow;
            }
            if (obj is Container)
            {
                foreach (var entry in (obj as Container))
                    Build(entry.Value);


                foreach (var entry in (obj as Container))
                    this.SharedContainer.Add(entry);
            }
            if (obj is ContainerValueResolver)
            {
                (obj as ContainerValueResolver).Container = this.SharedContainer;
            }

        }
    }
}
